#ifndef _CAMERA_CONTROLLER_H_
#define _CAMERA_CONTROLLER_H_

#include <osg/Referenced>
#include <osg/Camera>

class CameraController : public osg::Referenced
{
public:
	CameraController(osg::Camera *camera, float ratio);

	virtual void	resize(float ratio) = 0;
	virtual void	zoom(float dz) = 0;
	virtual void	move(float dx, float dy) = 0;
	virtual	void	rotate(float dx, float dy) = 0;

protected:
	void	changeZoom(float dz);

protected:
	osg::ref_ptr<osg::Camera> camera;
	float	zoomLevel;
	float	minZoomLevel;
	float	maxZoomLevel;
	float	ratio;
	float	sceneHWidth;
};

class CControllerPerspective : public CameraController
{
public:
	CControllerPerspective(osg::Camera *camera, float ratio);

	void	resize(float ratio);
	void	zoom(float dz);
	void	move(float dx, float dy);
	void	rotate(float dx, float dy);

private:
	void	checkAngle(float& angle);
	void	updateViewMatrix();
	float	ax;
	float	ay;
	float	x;
	float	y;
};

class CControllerIsometric : public CameraController
{
public:
	CControllerIsometric(osg::Camera *camera, float ratio);

	void	resize(float ratio);
	void	zoom(float dz);
	void	move(float dx, float dy);
	void	rotate(float dx, float dy) {}

private:
	void	updateProjection();
	void	updateViewMatrix();
	float	x;
	float	y;
	float	xpx;
	float	ypx;
};

class CControllerSideView : public CameraController
{
public:
	CControllerSideView(osg::Camera *camera, float ratio);

	void	resize(float ratio);
	void	zoom(float dz);
	void	move(float dx, float dy);
	void	rotate(float dx, float dy) {}

protected:
	virtual void	updateViewMatrix() = 0;

	float	x;
	float	y;

private:
	void	updateProjection();

	float	xpx;
	float	ypx;
};

class CControllerTopView : public CControllerSideView
{
public:
	CControllerTopView(osg::Camera *camera, float ratio);

protected:
	void	updateViewMatrix();
};

class CControllerBottomView : public CControllerSideView
{
public:
	CControllerBottomView(osg::Camera *camera, float ratio);

protected:
	void	updateViewMatrix();
};

class CControllerLeftView : public CControllerSideView
{
public:
	CControllerLeftView(osg::Camera *camera, float ratio);

protected:
	void	updateViewMatrix();
};

class CControllerRightView : public CControllerSideView
{
public:
	CControllerRightView(osg::Camera *camera, float ratio);

protected:
	void	updateViewMatrix();
};

class CControllerFrontView : public CControllerSideView
{
public:
	CControllerFrontView(osg::Camera *camera, float ratio);

protected:
	void	updateViewMatrix();
};

class CControllerBackView : public CControllerSideView
{
public:
	CControllerBackView(osg::Camera *camera, float ratio);

protected:
	void	updateViewMatrix();
};

#endif // _CAMERA_CONTROLLER_H_
